home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Mousetools
/
PWKeys
/
PWkeys2.0.asm
< prev
next >
Wrap
Assembly Source File
|
1996-09-26
|
42KB
|
1,647 lines
* PWkeys
* 1991 by Preben Nielsen
*
*
*HISTORY
* Made with Hisoft V2.12
*
* V1.0 20-Apr-91: This is first release. I made it over a year ago
* V1.1 06-May-91: Corrected a bug that appeared when trying to activate
* next/previous window when none was active
* 07-May-91: Added 'Refresh Window', 'Minimize Window' and
* 'Maximize Window'.
* 08-May-91: Added 'Sub Bitplane' and 'Add BitPlane' and
* 'Toggle Input-Lock'.
* 09-May-91: Added screen-blanking to 'Toggle Input-Lock'.
* 10-May-91: Added mouse-acceleration and sunmouse.
* 14-May-91: Added automatic and persistent screen-blanking.
* 15-May-91: Added automatic and persistent mouse-blanking.
* V2.0 18-May-91: Now I test for key-releases (saves time).
* 19-May-91: Help, I just found out that my "TellInputDevice"
* routine trashes memory-address 0 because it didn't
* do a "NewList" on its Message-port. It didn't cause
* any problems most of the time, but it has now been
* cured.
OPT O+
OPT O1+ ; Tells when a branch could be optimised to short
; OPT i+ ; Tells when '#' is probably missing.
incdir "AsmInc:"
include "exec/exec_lib.i"
include "exec/io.i"
include "exec/memory.i"
include "exec/interrupts.i"
include "devices/input.i"
include "devices/inputevent.i"
include "libraries/dos.i"
include "libraries/dosextens.i"
include "libraries/dos_lib.i"
include "graphics/gfxbase.i"
include "graphics/clip.i"
include "graphics/layers_lib.i"
include "graphics/graphics_lib.i"
include "intuition/intuitionbase.i"
include "intuition/intuition_lib.i"
include "Workbench/startup.i"
include "Workbench/workbench.i"
include "Workbench/icon_lib.i"
include "hardware/custom.i"
include "hardware/dmabits.i"
include "PWkeys.i"
V_EHB =$80
Prepare MACRO
IFC '\1','Exec_Call'
movea.l 4.W,A6
ENDC
IFC '\1','Icon_Call'
movea.l IconBase(DB),A6
ENDC
IFC '\1','Intuition_Call'
movea.l IntBase(DB),A6
ENDC
IFC '\1','Gfx_Call'
movea.l GFXBase(DB),A6
ENDC
IFC '\1','Dos_Call'
movea.l DosBase(DB),A6
ENDC
ENDM
CallLib MACRO
jsr _LVO\1(A6)
ENDM
Call MACRO
bsr \1
ENDM
CallS MACRO
bsr.S \1
ENDM
Push MACRO
movem.l \1,-(SP)
ENDM
Pop MACRO
movem.l (SP)+,\1
ENDM
PushS MACRO
move.l \1,-(SP)
ENDM
PopS MACRO
move.l (SP)+,\1
ENDM
rAPtr MACRO name
DefSiz set DefSiz+4
DefPtr set DefPtr-4
\1 = DefPtr
ENDM
rLong MACRO name
DefSiz set DefSiz+4
DefPtr set DefPtr-4
\1 = DefPtr
ENDM
rWord MACRO name
DefSiz set DefSiz+2
DefPtr set DefPtr-2
\1 = DefPtr
ENDM
rByte MACRO name
DefSiz set DefSiz+1
DefPtr set DefPtr-1
\1 = DefPtr
ENDM
rStorage MACRO name,size ; Define storage
DefSiz set DefSiz+\2
DefPtr set DefPtr-\2
\1 = DefPtr
ENDM
rEVEN MACRO ; Word boundary
IFNE DefPtr&1
DefPtr set DefPtr-1
DefSiz set DefSiz+1
ENDC
ENDM
rStart MACRO ; Define var section
DefPtr set 0
DefSiz set 0
ENDM
rEnd MACRO ; End var section
RelSize = DefSiz
ENDM
rAlloc MACRO ; Allocate vars
link DB,#-RelSize
ENDM
rFree MACRO ; Deallocate vars
unlk DB
ENDM
rClear MACRO ; Reset all vars
movem.l D0/DB,-(SP)
move.w #RelSize-1,D0
rClr.\@ clr.b -(DB)
dbf D0,rClr.\@
movem.l (SP)+,D0/DB
ENDM
ON_DISPLAY MACRO
move.w #BITSET|DMAF_RASTER,$DFF000+dmacon
ENDM
OFF_DISPLAY MACRO
move.w #BITCLR|DMAF_RASTER,$DFF000+dmacon
ENDM
TEST_DISPLAY MACRO
btst #DMAB_RASTER-8,$DFF000+dmaconr
ENDM
DB EQUR A4
SECTION PWkeys,CODE
InitProcess rAlloc ; Allocate memory for variables
rClear ; Clear the memory
subq.l #1,D0
move.l A0,CName(DB)
move.l D0,CLen(DB)
Prepare Exec_Call
CallLib Forbid
lea IHS+ihs_PortName(PC),A1
CallLib FindPort
move.l D0,HPort(DB)
CallLib Permit
suba.l A1,A1
CallLib FindTask ; Find us
move.l D0,PProcess(DB)
movea.l D0,A2
tst.l pr_CLI(A2)
bne.S CLIStart
WBStart lea pr_MsgPort(A2),A0
CallLib WaitPort ; Wait for a message
lea pr_MsgPort(A2),A0
CallLib GetMsg ; then get it
move.l D0,WBMsg(DB) ; save it for later reply
bra.S GetLibs
CLIStart move.l CName(DB),A0
move.l CLen(DB),D0
clr.b 0(A0,D0.W)
GetLibs lea DosName(PC),A1
CallLib OldOpenLibrary
move.l D0,DosBase(DB)
beq Error
tst.l HPort(DB) ; Install or Remove ?
bne.S LetsBegin
tst.l WBMsg(DB)
beq.S LetsBegin ; CLI or WB ?
clr.l CLen(DB) ; Signal that we haven't found args yet
move.l WBMsg(DB),A2
move.l sm_NumArgs(A2),D0 ; Any args ?
move.l sm_ArgList(A2),A2
subq.l #1,D0
blt.S LetsBegin
beq.S FoundArg
addq.w #wa_SIZEOF,A2 ; PROJECT !
FoundArg move.l wa_Lock(A2),D1
move.l wa_Name(A2),A2 ; Name of icon
beq.S NoLock
Prepare Dos_Call
CallLib CurrentDir
NoLock Prepare Exec_Call
lea IconName(PC),A1
CallLib OldOpenLibrary
move.l D0,IconBase(DB)
beq.S LetsBegin
Prepare Icon_Call
move.l A2,A0
CallLib GetDiskObject ; Get the icon
move.l D0,DiskObj(DB)
beq.S LetsBegin
move.l D0,A2
move.l do_ToolTypes(A2),A0
lea FileTxt(PC),A1
CallLib FindToolType ; Find 'FILE=????'
move.l D0,CName(DB)
move.l D0,CLen(DB) ; Signal that we have or haven't found args
LetsBegin tst.l HPort(DB)
beq.S DoInstall
DoRemove moveq #REMOVED,D7
lea IHS(PC),A0
lea PSEndIHS1(PC),A1
lea PSEndIHS2(PC),A2
Call RemoveHandler
beq.S ShowMsg
moveq #CANTREMOVE,D7
bra.S ShowMsg
DoInstall moveq #INSTALLED,D7
lea IHS(PC),A0
lea PSPrepIHS1(PC),A1
lea PSPrepIHS2(PC),A2
Call InstallHandler
beq.S ShowMsg
moveq #CANTINSTALL,D7
ShowMsg move.l D7,D0
Call CONMsg
Error
Exit Prepare Exec_Call
FreeDos move.l DosBase(DB),D0
beq.S ReplyWB
move.l D0,A1
CallLib CloseLibrary
ReplyWB move.l WBMsg(DB),D0
beq.S AllDone
move.l DiskObj(DB),D0
beq.S FreeIcon
move.l D0,A0
Prepare Icon_Call
CallLib FreeDiskObject
FreeIcon Prepare Exec_Call
move.l IconBase(DB),D0
beq.S WBEnd
move.l D0,A1
CallLib CloseLibrary
WBEnd CallLib Forbid ; We were started from WB
move.l WBMsg(DB),A1
CallLib ReplyMsg ; Reply WBMessage
AllDone rFree
moveq #0,D0
rts
FHandle EQUR D5
* Call: D0 = Msg-number
CONMsg Push D0-D7/A0-A6
Prepare Dos_Call
move.l D0,D4
moveq #0,D6
CallLib Output
move.l D0,FHandle
bne.S 1$
moveq #1,D6
lea CONName(PC),A0
move.l A0,D1
move.l #MODE_OLDFILE,D2
CallLib Open
move.l D0,FHandle
beq.S 2$
1$ moveq #INFOMSG,D0
Call SendMsg
move.l D4,D0
Call SendMsg
tst.l D6
beq.S 2$
moveq #127,D1
CallLib Delay
move.l FHandle,D1
CallLib Close
2$ Pop D0-D7/A0-A6
rts
* Call: D0 = Msg-number
SendMsg neg.l D0
lsl.l #1,D0
lea MsgTable(PC),A0
add.w 0(A0,D0),A0
move.l A0,D2
moveq #-1,D3
1$ addq.l #1,D3
tst.b (A0)+
bne.S 1$
move.l FHandle,D1
Prepare Dos_Call
CallLib Write
rts
INFOMSG =0
INSTALLED =-1
REMOVED =-2
CANTINSTALL =-3
CANTREMOVE =-4
MsgText MACRO
dc.w \1-MsgTable
ENDM
MsgTable MsgText Msg
MsgText Msg1
MsgText Msg2
MsgText Msg3
MsgText Msg4
CONName dc.b 'CON:100/60/330/63/PWkeys',0
Msg PWkeys_CON_Msg
Msg1 dc.b 'has just been installed...',10,0
Msg2 dc.b 'has just been removed...',10,0
Msg3 dc.b 'Error: Cannot install handler',10,0
Msg4 dc.b 'Error: Cannot remove handler',10,0
EVEN
rtsValue EQUR D7
* This is general-purpose inputhandler removal-routine
* It only needs an ihs with a port-name to remove the handler
* Call: A0 = ihs
* A1 = first ihs-installation-routine or NULL
* A2 = second ihs-installation-routine or NULL
* Return: D0 = 0 means succes
RemoveHandler Push D1/rtsValue/A0-A3/A6
moveq #-1,rtsValue
move.l A2,A3
move.l A0,A2
move.l A1,D1
beq.S 1$
jsr (A1) ; A0 = ihs
beq.S 2$
move.l D0,A2
1$ move.l A2,A0
Prepare Exec_Call
moveq #IND_REMHANDLER,D0
Call TellInputDevice
move.l D0,rtsValue
bne.S 2$
lea ihs_Port(A2),A1
CallLib RemPort
moveq #0,D0
bra.S 3$
2$ moveq #-1,D0
3$ move.l A3,D1
beq.S 4$
move.l A2,A0
jsr (A3) ; A0 = ihs, D0 = 0 means succes
4$ move.l rtsValue,D0
Pop D1/rtsValue/A0-A3/A6
rts
* This is general-purpose inputhandler installation-routine
* It only needs an ihs with a port-name to install the handler
* Call: A0 = ihs
* A1 = first ihs-installation-routine or NULL
* A2 = second ihs-installation-routine or NULL
* Return: D0 = 0 means succes
InstallHandler Push D1/rtsValue/A0-A3/A6
moveq #-1,rtsValue
move.l A2,A3
move.l A0,A2
move.l A1,D1
beq.S 1$
jsr (A1) ; A0 = ihs
beq.S 2$
move.l D0,A2
1$ move.l A2,A0
moveq #IND_ADDHANDLER,D0
Call TellInputDevice
move.l D0,rtsValue
bne.S 2$
lea ihs_Port(A2),A1
lea ihs_PortName(A2),A0
move.l A0,MP+LN_NAME(A1) ;MsgPort->mp_Node.ln_Name=Name;
clr.b MP+LN_PRI(A1) ;MsgPort->mp_Node.ln_Pri =0;
move.b #NT_MSGPORT,MP+LN_TYPE(A1) ;MsgPort->mp_Node.ln_Type=NT_MSGPORT;
move.b #PA_IGNORE,MP_FLAGS(A1) ;MsgPort->mp_Flags =PA_IGNORE;
Prepare Exec_Call
CallLib AddPort
moveq #0,D0
bra.S 3$
2$ moveq #-1,D0
3$ move.l A3,D1
beq.S 4$
move.l A2,A0
jsr (A3) ; A0 = ihs, D0 = 0 means succes
4$ move.l rtsValue,D0
Pop D1/rtsValue/A0-A3/A6
rts
* Open the input device. Set up the I/O block to add or remove the
* input handler, and send the request to the input device. Finally,
* close the device
* Call: A0 = ihs
* D0 = Function to perform (IND_ADDHANDLER/IND_REMHANDLER)
* Return: D0 = 0 means succes
TellInputDevice Push D1-D2/rtsValue/A0-A3/A6
Prepare Exec_Call
moveq #-1,rtsValue
move.l D0,D2
move.l A0,A2
lea IReq(DB),A0
moveq #IOSTD_SIZE,D0
Call MemClear
lea IPort(DB),A0
moveq #MP_SIZE,D0
Call MemClear
move.l A0,A3
move.b #NT_MSGPORT,MP+LN_TYPE(A3) ; mp_Node.ln_Type=NT_MSGPORT;
move.b #PA_SIGNAL,MP_FLAGS(A3) ; mp_Flags =PA_SIGNAL;
moveq #-1,D0
CallLib AllocSignal
move.b D0,MP_SIGBIT(A3) ; mp_SigBit =MPSigBit;
bmi.S 2$
suba.l A1,A1
CallLib FindTask
move.l D0,MP_SIGTASK(A3) ; mp_SigTask =FindTask(0);
lea MP_MSGLIST(A3),A0
NEWLIST A0
lea IReq(DB),A1
move.l A3,IO+MN_REPLYPORT(A1) ; ExtReq->io_Message.mn_ReplyPort =taskReplyPort;
move.b #NT_MESSAGE,IO+MN+LN_TYPE(A1) ; ExtReq->io_Message.mn_Node.ln_Type=NT_MESSAGE;
lea InputName(PC),A0 ; input.device
moveq #0,D0 ; unit#
moveq #0,D1 ; flags
CallLib OpenDevice
tst.w D0 ; flag: error if > 0
bne.S 1$
lea IReq(DB),A1
move.w D2,IO_COMMAND(A1)
lea ihs_Interrupt(A2),A0
move.l A0,IO_DATA(A1)
CallLib DoIO
move.l D0,rtsValue
lea IReq(DB),A1
CallLib CloseDevice
1$ move.b MP_SIGBIT(A3),D0
CallLib FreeSignal
2$ move.l rtsValue,D0
Pop D1-D2/rtsValue/A0-A3/A6
rts
* Call: A0 = Memory area
* D0:16 = Count
MemClear Push D0-D1/A0
moveq #0,D1
bra.S 2$
1$ move.b D1,(A0)+
2$ dbf D0,1$
Pop D0-D1/A0
rts
* Call: A0 = Source
* A1 = Destination
* D0:16= Count
MemCopy Push D0/A0-A1
bra.S 2$
1$ move.b (A0)+,(A1)+
2$ dbf D0,1$
Pop D0/A0-A1
rts
* Each handler should have such a pair of installation-routine
* The first one is passed to InstallHandler in A1 and it
* is called immediately when entering InstallHandler
* The second one is passed to InstallHandler in A2 and it
* is called after attempt to install handler and message-port
* -----------------------------------------------------------------
* Call: A0 = ihs
* Return: D0 has to point to ihs to be used when installation proceeds
* If D0 = 0 then installation is aborted
PSPrepIHS1 Push D1-D2/A0-A3/A6
moveq #0,D2
Call GetKeys
beq 2$
Prepare Exec_Call
lea Entry(PC),A0
CallLib AllocEntry
move.l D0,MEntry(DB)
bmi.S 2$ ; Is bit 31 set ?
move.l D0,A3
move.l ML_ME+0*ME_SIZE(A3),A2
lea IHS(PC),A0
move.l A2,A1
move.w #HandlerSize,D0
Call MemCopy ; Copy handler
lea ChipData(PC),A0
move.l ML_ME+1*ME_SIZE(A3),A1
move.w #ChipSize,D0
Call MemCopy ; Copy CHIP-data
move.l A1,NewCopper-IHS(A2)
lea MySprite-ChipData(A1),A1
move.l A1,NewSprite-IHS(A2)
move.b PWkPri(PC),ihs_Interrupt+LN_PRI(A2) ; HandlerBlock.HInterrupt.is_Node.ln_Pri = PRI;
lea HandlerCode-IHS(A2),A0
move.l A0,ihs_Interrupt+IS_CODE(A2) ; HandlerBlock.HInterrupt.is_Code = Handler
lea PWkVersionID-IHS(A2),A0
move.l A0,ihs_Interrupt+IS_DATA(A2) ; HandlerBlock.HInterrupt.is_Data = KeyDefines;
move.w #HStartFlags,ihs_Flags(A2)
move.l A3,ihs_MemEntry(A2)
lea LayerName(PC),A1 ; Libraries won't get closed
CallLib OldOpenLibrary
move.l D0,LAYERbase-IHS(A2)
beq.S 2$
lea GfxName(PC),A1
CallLib OldOpenLibrary
move.l D0,GFXbase-IHS(A2)
beq.S 2$
lea IntName(PC),A1
CallLib OldOpenLibrary
move.l D0,INTUIbase-IHS(A2)
beq.S 2$
move.l A2,D2
2$ move.l D2,D0
Pop D1-D2/A0-A3/A6
rts
* Call: A0 = ihs
* D0 = 0 means everything went perfect
* -1 means something went wrong during installation
PSPrepIHS2 Push D0-D1/A0-A1/A6
tst.l D0
beq.S 1$
move.l MEntry(DB),D0
bmi.S 1$ ; Is bit 31 set ?
move.l D0,A0
Prepare Exec_Call
CallLib FreeEntry
1$ Pop D0-D1/A0-A1/A6
rts
* Each handler should have such a pair of ending-routine
* The first one is passed to RemoveHandler in A1 and it
* is called immediately when entering RemoveHandler
* The second one is passed to RemoveHandler in A2 and it
* is called after attempt to remove handler and message-port
* -----------------------------------------------------------------
* Call: A0 = ihs
* Return: D0 has to point to ihs to be used when removal proceeds
* If D0 = 0 then removal is aborted
PSEndIHS1 Push D1-D2/A0-A1/A6
Prepare Exec_Call
CallLib Forbid
lea ihs_PortName(A0),A1
CallLib FindPort
move.l D0,D2
CallLib Permit
move.l D2,D0 ; Does Forbid/Permit destroy scratch-registers ?
Pop D1-D2/A0-A1/A6
rts
* Call: A0 = ihs
* D0 = 0 means everything went perfect
* -1 means something went wrong during removal
PSEndIHS2 Push D0-D1/A0-A1/A6
tst.l D0
bmi.S 1$
move.l ihs_MemEntry(A0),A0
Prepare Exec_Call
CallLib FreeEntry
1$ Pop D0-D1/A0-A1/A6
rts
* Tries to read hotkeys from file (if any is specified)
* Return: D0 = 0 means failure
GetKeys Push D1-D7/A0-A6
moveq #1,rtsValue
tst.l CLen(DB)
beq.S 2$
moveq #0,rtsValue
Prepare Dos_Call
move.l CName(DB),D1
move.l #MODE_OLDFILE,D2
CallLib Open
move.l D0,D4
beq.S 2$
move.l D0,D1
lea TBuf(DB),A0
move.l A0,D2
move.l #pw_SIZE,D3
CallLib Read
cmp.l D0,D3
bne.S 1$
lea TBuf(DB),A0
movem.l pw_ID(A0),D0-D1
movem.l PWkVersionID(PC),D2-D3
cmp.l D0,D2
bne.S 1$
cmp.l D1,D3
bne.S 1$
lea PWkVersionID(PC),A1
move.l #pw_SIZE,D0
Call MemCopy
moveq #1,rtsValue
1$ move.l D4,D1
CallLib Close
2$ move.l rtsValue,D0
Pop D1-D7/A0-A6
rts
* »»»»»»»»»»»»»»»»»»»»»» Data-definition start «««««««««««««««««««««««
rStart
rLong CLen
rAPtr CName
rAPtr PProcess
rAPtr WBMsg
rAPtr DosBase
rAPtr IconBase
rAPtr DiskObj
rAPtr HPort
rAPtr MEntry
rStorage IReq,IOSTD_SIZE
rStorage IPort,MP_SIZE
rStorage TBuf,pw_SIZE
rEnd
DosName dc.b 'dos.library',0
LayerName dc.b 'layers.library',0
GfxName dc.b 'graphics.library',0
IntName dc.b 'intuition.library',0
IconName dc.b 'icon.library',0
InputName dc.b 'input.device',0
FileTxt dc.b 'FILE',0
EVEN
Entry ds.b LN_SIZE
dc.w 2
dc.l MEMF_CLEAR|MEMF_PUBLIC
dc.l HandlerSize
dc.l MEMF_CLEAR|MEMF_CHIP
dc.l ChipSize
* »»»»»»»»»»»»»»»»»»»»»» Data-definition end «««««««««««««««««««««««««
* »»»»»»»»»»»»»»»»»»»»»» Input-handler start «««««««««««««««««««««««««
HDisabled =0
HNoExtRemoval =1
HInputDisabled =2
HAccelMouse =3
HSunMouse =4
HScreenBlanked =5
HMouseBlanked =6
HStartFlags =0
* This is the handler-block
IHS ihs_Start
* Local variables
Chain dc.l 0
OldSprite dc.l 0
NewSprite dc.l 0
NewCopper dc.l 0
INTUIbase dc.l 0
GFXbase dc.l 0
LAYERbase dc.l 0
* This is the beginning of the part coming from a file
PWkVersionID dc.l 'PWKF'
PWkVersionNum dc.w PWkeysVersion,PWkeysRevision
PWkPri dc.b PWkeysPri,0
PWkMouseAccel dc.b PWkeysMSpeed
PWkMouseThresh dc.b PWkeysMThresh
PWkMTimeout dc.l PWkeysMTimeout
PWkSTimeout dc.l PWkeysSTimeout
PWkMWaitTime dc.l 0
PWkSWaitTime dc.l 0
PWkHotKeys dc.w KeyFuncNumber
* These defines are the default when no file is specified
* Keep them sorted on 'Code|Qual'
KeyDefines HotKey KP1,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_LEFT_BOTTOM
HotKey KP2,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_BOTTOM
HotKey KP3,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_RIGHT_BOTTOM
HotKey KP4,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_LEFT
HotKey KP5,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_CENTER
HotKey KP6,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_RIGHT
HotKey KP7,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_LEFT_TOP
HotKey KP8,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_TOP
HotKey KP9,LSHIFT|LAMIGA,LSHIFT|LAMIGA,W_TO_RIGHT_TOP
HotKey BACKSPACE,LAMIGA|RAMIGA,LAMIGA|RAMIGA,TOGGLE_INPUTLOCK
HotKey TAB,LSHIFT|LAMIGA,LSHIFT|LAMIGA,REFRESH_W
HotKey DEL,LAMIGA|RAMIGA,LAMIGA|RAMIGA,TOGGLE_FASTMOUSE
HotKey UPARROW,LAMIGA,SHIFT|AMIGA,FRONT_W_TO_BACK
HotKey UPARROW,LSHIFT|LAMIGA,SHIFT|AMIGA,W_TO_BACK
HotKey UPARROW,RSHIFT|RAMIGA,SHIFT|AMIGA,FRONT_S_TO_BACK
HotKey DOWNARROW,LAMIGA,SHIFT|AMIGA,BACK_W_TO_FRONT
HotKey DOWNARROW,LSHIFT|LAMIGA,SHIFT|AMIGA,W_TO_FRONT
HotKey DOWNARROW,RSHIFT|RAMIGA,SHIFT|AMIGA,BACK_S_TO_FRONT
HotKey RIGHTARROW,LSHIFT|LAMIGA,LSHIFT|LAMIGA,ACTIVATE_NEXT_W
HotKey LEFTARROW,LSHIFT|LAMIGA,LSHIFT|LAMIGA,ACTIVATE_PREV_W
HotKey F1,LSHIFT|LAMIGA,LSHIFT|LAMIGA,MINIMIZE_W
HotKey F2,LSHIFT|LAMIGA,LSHIFT|LAMIGA,MAXIMIZE_W
HotKey F9,RSHIFT|RAMIGA,RSHIFT|RAMIGA,SUB_BITPLANE
HotKey F10,RSHIFT|RAMIGA,RSHIFT|RAMIGA,ADD_BITPLANE
HotKey HELP,LAMIGA|RAMIGA,LAMIGA|RAMIGA,TOGGLE_SUNMOUSE
* This is the end of the part coming from a file
* This table below defines the connection between the
* selected hotkey and the function to perform
JmpEntry_SIZE =2
JmpEntry MACRO
dc.w \1-JmpTable
ENDM
JmpTable JmpEntry WinToTop
JmpEntry WinToBottom
JmpEntry WinToLeft
JmpEntry WinToRight
JmpEntry WinToTL
JmpEntry WinToBL
JmpEntry WinToTR
JmpEntry WinToBR
JmpEntry WinToCenter
JmpEntry WinToFront
JmpEntry WinToBack
JmpEntry BackWinToFront
JmpEntry FrontWinToBack
JmpEntry ActivatePrevWin
JmpEntry ActivateNextWin
JmpEntry MinimizeWin
JmpEntry MaximizeWin
JmpEntry RefreshWin
JmpEntry BackScrToFront
JmpEntry FrontScrToBack
JmpEntry SubBitplane
JmpEntry AddBitplane
JmpEntry ToggleInputLock
JmpEntry ToggleFastMouse
JmpEntry ToggleSunMouse
* Handler()
* This is the input handler. For each event in the event list:
* If the event is a raw key event, then
* make the KeyCode longword for that event's code and qualifier,
* binary search the KeyDefines[] array for a matching entry (only consider
* the qualifiers specified by the HotKey_Mask). Since most keys pressed
* will NOT match a hot-key, we want the search to be as fast as
* possible, so we use a binary search rather than a linear search.
* if the key was not a hot key,
* go on to the next key
* otherwise,
* perform the function for the specified hot key,
* remove the hot key from the event list.
* When all the events have been checked, return the event list so that
* Intuition can do its thing.
* Subroutines that uses other registers than the ones below, has
* to save them first and restore them afterwards.
SD EQUR D0 ; Scratch data register
Accel EQUR D1 ; Acceleration
Thresh EQUR D2 ; Threshold
Min EQUR D1 ; For binary search
Max EQUR D2 ; For binary search
Num EQUR D3 ; For binary search
TheKey EQUR D4 ; For binary search
SA EQUR A0 ; Scratch address register
Hkey EQUR A1 ; Hotkey
PEvent EQUR A2 ; Previous Event
Event EQUR A3 ; This Event
StatusBits =IHS+ihs_Flags+1
Next =ie_NextEvent
Class =ie_Class
Code =ie_Code
Qual =ie_Qualifier
Seconds =ie_TimeStamp+TV_SECS
Micros =ie_TimeStamp+TV_MICRO
ButtonsQual =IEQUALIFIER_MIDBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_LEFTBUTTON
* Call: A0 = List of InputEvents, A1 = HandlerData
HandlerCode Push D1-D4/A0-A3
lea Chain(PC),PEvent
move.l A0,Next(PEvent)
btst #HDisabled,StatusBits(PC) ; Future feature
bne NoMoreEvents
ieLoop move.l Next(PEvent),Event
move.l Event,SD
beq NoMoreEvents
* Process TIMER events
CheckTimer cmpi.b #IECLASS_TIMER,Class(Event)
bne.S CheckMouse
CheckSBlanking btst #HScreenBlanked,StatusBits(PC)
bne.S ForceSBlanking
move.l PWkSWaitTime(PC),SD
beq.S CheckMBlanking
cmp.l Seconds(Event),SD
bge.S CheckMBlanking
ForceSBlanking TEST_DISPLAY ; Screen should be blanked !
beq NeverRemove
Call BlankScreen ; But is isn't, so I blank it !
bra NeverRemove
CheckMBlanking btst #HMouseBlanked,StatusBits(PC)
bne.S ForceMBlanking
move.l PWkMWaitTime(PC),SD
beq NeverRemove
cmp.l Seconds(Event),SD
bge NeverRemove
ForceMBlanking move.l GFXbase(PC),SA ; Mouse should be blanked !
move.l gb_copinit(SA),SA
move.w copinit_sprstrtup+2(SA),SD
swap SD
move.w copinit_sprstrtup+6(SA),SD
cmp.l NewSprite(PC),SD
beq NeverRemove
Call BlankMouse ; But it isn't, so I blank it now !
bra NeverRemove
* Process RAWMOUSE events
CheckMouse cmpi.b #IECLASS_RAWMOUSE,Class(Event)
bne.S CheckKey
btst #HInputDisabled,StatusBits(PC)
bne Remove
Call BreakSBlanking
Call BreakMBlanking
CheckFastMouse btst #HAccelMouse,StatusBits(PC)
beq.S CheckSunMouse
cmpi.w #IECODE_NOBUTTON,Code(Event)
bne NeverRemove
move.w Qual(Event),SD
andi.w #ButtonsQual,SD
bne NeverRemove
moveq #0,Accel
moveq #0,Thresh
move.b PWkMouseAccel(PC),Accel
move.b PWkMouseThresh(PC),Thresh
move.w ie_X(Event),D0
Call CalcNewPos
move.w D0,ie_X(Event)
move.w ie_Y(Event),D0
Call CalcNewPos
move.w D0,ie_Y(Event)
CheckSunMouse btst #HSunMouse,StatusBits(PC)
beq NeverRemove
Call ActivateMWindow
bra NeverRemove
* Process RAWKey events
CheckKey cmpi.b #IECLASS_RAWKEY,Class(Event)
bne NeverRemove
move.w Code(Event),TheKey ; Construct a 'Code|Qual' long-word
btst #7,TheKey ; Is it a key-release ?
bne DontRemoveKey
swap TheKey ; It is a key-press !
move.w Qual(Event),TheKey
move.w PWkHotKeys(PC),Max ; Do Binary-search
moveq #-1,Min
SearchLoop move.w Max,Num
add.w Min,Num
asr.w #1,Num
cmp.w Num,Min
beq.S DontRemoveKey ; Didn't find a match
move.w Num,SD
lsl.w #3,SD ; HotKey_SIZE * Num
lea KeyDefines(PC),Hkey
add.w SD,Hkey
move.l TheKey,SD
and.l HotKey_Mask(Hkey),SD ; TheKey & KeyDefines[Num].HotKey_Mask
cmp.l HotKey_ID(Hkey),SD ; A match ?
beq.S Perform
blt.S LookLower
LookHigher move.l Num,Min ; (TheKey & KeyDefines[Num].HotKey_Mask) > KeyDefines[Num].HotKey_ID
bra.S SearchLoop
LookLower move.l Num,Max ; (TheKey & KeyDefines[Num].HotKey_Mask) < KeyDefines[Num].HotKey_ID
bra.S SearchLoop
* Found a match
* Hkey = Hotkey
Perform Push D0-D7/A0-A6 ; (TheKey & KeyDefines[Num].HotKey_Mask) = KeyDefines[Num].HotKey_ID
moveq #0,D0
move.b HotKey_Func(Hkey),D0 ; KeyDefines[Num].HotKey_Func
lsl.w #1,D0 ; JmpEntry_SIZE * KeyDefines[Num].HotKey_Func
lea JmpTable(PC),A2
add.w 0(A2,D0.W),A2
btst #HInputDisabled,StatusBits(PC)
beq.S 1$
lea ToggleInputLock(PC),A0
cmp.l A2,A0
bne.S 2$
1$ Prepare Exec_Call
CallLib Forbid
move.l INTUIbase(PC),A6 ; Intuitionbase stays loaded
jsr (A2) ; Jump to function
Prepare Exec_Call
CallLib Permit
2$ Pop D0-D7/A0-A6
RemoveKey btst #HInputDisabled,StatusBits(PC)
bne.S Remove
Call BreakSBlanking
Remove move.l Next(Event),Next(PEvent); Remove event from chain and move on to next Event
bra ieLoop
DontRemoveKey btst #HInputDisabled,StatusBits(PC)
bne.S Remove
Call BreakSBlanking
NeverRemove move.l Event,PEvent ; Just move on to next Event
bra ieLoop
NoMoreEvents Pop D1-D4/A0-A3
move.l Chain(PC),D0 ; Return (shortened ?) chain
rts
* »»»»»»»»»»» Misc functions called by the hotkey-functions ««««««««««
* Call: A0 = Window to check
* Return: Z-flag set if no active stringgadget or system-gadget
* in the window or in any active requester in the window
* Destroys no registers
CheckWindow Push D0/A1
move.l wd_FirstRequest(A0),D0
beq.S TestWin
ReqCLoop tst.l D0
beq.S WinCEnd
move.l D0,A1
move.w rq_Flags(A1),D0
andi.w #REQACTIVE,D0
beq.S NextReq
move.l rq_ReqGadget(A1),D0
bra.S GadCLoop ; Found an active requester
NextReq move.l rq_OlderRequest(A1),D0
bra.S ReqCLoop
TestWin move.l wd_FirstGadget(A0),D0
* D0 = Gadgetlist to check
GadCLoop tst.l D0
beq.S WinCEnd
move.l D0,A1
move.w gg_GadgetType(A1),D0
andi.w #SYSGADGET,D0
bne.S CheckSELECT
move.w gg_GadgetType(A1),D0
andi.w #STRGADGET,D0
beq.S NextGad
CheckSELECT move.w gg_Flags(A1),D0
andi.w #SELECTED,D0
beq.S NextGad
moveq #1,D0 ; Window contains an active string-gadget
bra.S WinCEnd ; or an active system-gadget
NextGad move.l gg_NextGadget(A1),D0
bra.S GadCLoop
WinCEnd Pop D0/A1
rts
* TopScreen()
* Find the top screen
* Return: D0 = Screen or NULL
* Destroys D0-D1/A0-A1
TopScreen move.l ib_FirstScreen(A6),D0
rts
* BottomScreen()
* Find the bottom screen
* Return: D0 = Screen or NULL
* Destroys D0-D1/A0-A1
BottomScreen move.l ib_FirstScreen(A6),D0
beq.S 2$
1$ move.l D0,A0
move.l sc_NextScreen(A0),D0
bne.S 1$
move.l A0,D0
2$ rts
* TopWindow()
* Find the top window of the specified screen. Start at the top
* layer of the screen and move backward as long as the layer exists
* and has no window connected to it. Return the window associated
* with the final layer, if any.
* Call : A0 = Screen
* Return: D0 = Window or NULL
* Destroys D0-D1/A0-A1
TopWindow move.l sc_LayerInfo+li_top_layer(A0),A0
moveq #0,D0
1$ move.l A0,D1
beq.S 2$
move.l lr_Window(A0),D0
bne.S 2$
move.l lr_back(A0),A0
bra.S 1$
2$ tst.l D0
rts
* BottomWindow()
* Find the bottom window of the specified screen. Start at the top
* layer and as long as the layer exists, go to the next layer back.
* If the layer has a window attached, consider that to be the bottom
* window until a lower one is found.
* Call : A0 = Screen
* Return: D0 = Window or NULL
* Destroys D0-D1/A0-A1
BottomWindow move.l sc_LayerInfo+li_top_layer(A0),A0
moveq #0,D0
1$ move.l A0,D1
beq.S 3$
move.l lr_Window(A0),D1
beq.S 2$
move.l D1,D0
2$ move.l lr_back(A0),A0
bra.S 1$
3$ tst.l D0
rts
* NextWindow()
* Find the next window below the specified window (wrap arround to
* the top if the window is the bottom one). Start with the window's
* layer and go back until a layer with a window is found, or no more
* layers exist. If a window was found, return it, otherwise, use the
* top window.
* Call : A0 = Window
* Return: D0 = Next Window or NULL
* Destroys D0-D1/A0-A1
NextWindow moveq #0,D0
move.l wd_WLayer(A0),A1
1$ move.l lr_back(A1),D1
beq.S 2$
move.l D1,A1
move.l lr_Window(A1),D0
beq.S 1$
cmp.l A0,D0
beq.S 1$
2$ tst.l D0
rts
* PreviousWindow()
* Find the window that is on top of the specified window (or NULL if there
* are no windows above it). Start with the window's layer, and move to
* the layer in front until a layer with a (different) window is found, or
* until no more layers exist. If a window was found, return it, otherwise
* return NULL.
* Call : A0 = Window
* Return: D0 = Previous Window or NULL
* Destroys D0-D1/A0-A1
PrevWindow moveq #0,D0
move.l wd_WLayer(A0),A1
1$ move.l lr_front(A1),D1
beq.S 2$
move.l D1,A1
move.l lr_Window(A1),D0
beq.S 1$
cmp.l A0,D0
beq.S 1$
2$ tst.l D0
rts
ScreenToBack jmp _LVOScreenToBack(A6)
ScreenToFront jmp _LVOScreenToFront(A6)
WindowToBack Call CheckWindow
bne.S WinErr
jmp _LVOWindowToBack(A6)
WindowToFront Call CheckWindow
bne.S WinErr
jmp _LVOWindowToFront(A6)
ActivateWindow Call CheckWindow
bne.S WinErr
jmp _LVOActivateWindow(A6)
MoveWindow Call CheckWindow
bne.S WinErr
jmp _LVOMoveWindow(A6)
SizeWindow Call CheckWindow
bne.S WinErr
jmp _LVOSizeWindow(A6)
WinErr rts
* »»»»»»»»»»»»»»»»»»» Window manipulating functions ««««««««««««««««««
* Move the active window in x/y directions
* Destroys D0-D1/A0-A2
WinToTop lea TopIt(PC),A1 ; Window To Top
lea DontMoveX(PC),A2
bra.S WindowMove
WinToBottom lea BottomIt(PC),A1 ; Window To Bottom
lea DontMoveX(PC),A2
bra.S WindowMove
WinToLeft lea DontMoveY(PC),A1 ; Window To Left
lea LeftIt(PC),A2
bra.S WindowMove
WinToRight lea DontMoveY(PC),A1 ; Window To Right
lea RightIt(PC),A2
bra.S WindowMove
WinToTL lea TopIt(PC),A1 ; Window To Upper Left Corner
lea LeftIt(PC),A2
bra.S WindowMove
WinToTR lea TopIt(PC),A1 ; Window To Upper Right Corner
lea RightIt(PC),A2
bra.S WindowMove
WinToBL lea BottomIt(PC),A1 ; Window To Lower Left Corner
lea LeftIt(PC),A2
bra.S WindowMove
WinToBR lea BottomIt(PC),A1 ; Window To Lower Right Corner
lea RightIt(PC),A2
bra.S WindowMove
WinToCenter lea CenterHeight(PC),A1 ; Window To Center
lea CenterWidth(PC),A2
* Call: A1 = Function to adjust position in y-direction
* A2 = Function to adjust position in x-direction
WindowMove move.l ib_ActiveWindow(A6),D0
beq.S 2$
move.l D0,A0
jsr (A1)
move.w D0,D1
jsr (A2)
bne.S 1$
tst.w D1
beq.S 2$
1$ Call MoveWindow
2$ rts
DontMoveX
DontMoveY moveq #0,D0
rts
* Call: A0 = Window
CenterHeight move.l wd_WScreen(A0),A1
move.w sc_Height(A1),D0
sub.w wd_Height(A0),D0
asr.w #1,D0
sub.w wd_TopEdge(A0),D0
rts
* Call: A0 = Window
CenterWidth move.l wd_WScreen(A0),A1
move.w sc_Width(A1),D0
sub.w wd_Width(A0),D0
asr.w #1,D0
sub.w wd_LeftEdge(A0),D0
rts
* Call: A0 = Window
BottomIt move.l wd_WScreen(A0),A1
move.w sc_Height(A1),D0
sub.w wd_TopEdge(A0),D0
sub.w wd_Height(A0),D0
rts
* Call: A0 = Window
RightIt move.l wd_WScreen(A0),A1
move.w sc_Width(A1),D0
sub.w wd_LeftEdge(A0),D0
sub.w wd_Width(A0),D0
rts
* Call: A0 = Window
TopIt move.w wd_TopEdge(A0),D0
neg.w D0
rts
* Call: A0 = Window
LeftIt move.w wd_LeftEdge(A0),D0
neg.w D0
rts
* WinToFront()
* Send the active window to the top of the list.
* Destroys D0-D2/A0-A1
WinToFront move.l ib_ActiveScreen(A6),D0
beq.S 1$
move.l ib_ActiveWindow(A6),D2
beq.S 1$
move.l D0,A0
Call TopWindow
cmp.l D0,D2 ; Same window ? (NOT NULL !)
beq.S 1$
move.l D2,A0
Call WindowToFront
1$ rts
* WinToBack()
* Send the active window to the back of the list.
* Destroys D0-D2/A0-A1
WinToBack move.l ib_ActiveScreen(A6),D0
beq.S 1$
move.l ib_ActiveWindow(A6),D2
beq.S 1$
move.l D0,A0
Call BottomWindow
cmp.l D0,D2 ; Same window ? (NOT NULL !)
beq.S 1$
move.l D2,A0
Call WindowToBack
1$ rts
* BackWindowToFront()
* Move the bottom window to the top and activate it.
* Get the bottom window, skipping over backdrop windows. If one
* is found, bring it to the front, and activate it.
* Destroys D0-D2/A0-A1
BackWinToFront move.l ib_ActiveScreen(A6),D0
beq.S 3$
move.l D0,A0
Call BottomWindow
1$ move.l D0,A0
tst.l D0
beq.S 3$
btst #0,wd_Flags+2(A0) ; BackDrop ?
beq.S 2$
Call PrevWindow
bra.S 1$
2$ move.l A0,D2
Call WindowToFront
move.l D2,A0
Call ActivateWindow
3$ rts
* FrontWindowToBack()
* Move the top window to the back, and activate the new top window.
* Get the top window, send it top to the back, and activate the top
* window.
* Destroys D0-D2/A0-A1
FrontWinToBack move.l ib_ActiveScreen(A6),D2
beq.S 1$
move.l D2,A0
Call TopWindow
beq.S 1$
move.l D0,A0
Call WindowToBack
move.l D2,A0
Call TopWindow
beq.S 1$
move.l D0,A0
Call ActivateWindow
1$ rts
* ActivatePreviousWindow()
* Get the window previous to the active window (if none, then get the
* bottom window in the active screen), and activate that window.
* Destroys D0-D2/A0-A1
ActivatePrevWin move.l ib_ActiveScreen(A6),D2
beq.S 3$
move.l ib_ActiveWindow(A6),D0
beq.S 1$
move.l D0,A0
Call PrevWindow
bne.S 2$
move.l D2,A0
Call BottomWindow
bra.S 2$
1$ move.l D2,A0
move.l sc_FirstWindow(A0),D0
2$ beq.S 3$
move.l D0,A0
Call ActivateWindow
3$ rts
* ActivateNextWindow()
* Get the window below the active window and activate it.
* Destroys D0-D2/A0-A1
ActivateNextWin move.l ib_ActiveScreen(A6),D2
beq.S 3$
move.l ib_ActiveWindow(A6),D0
beq.S 1$
move.l D0,A0
Call NextWindow
bne.S 2$
move.l D2,A0
Call TopWindow
bra.S 2$
1$ move.l D2,A0
move.l sc_FirstWindow(A0),D0
2$ beq.S 3$
move.l D0,A0
Call ActivateWindow
3$ rts
* Size the active window in x/y directions
* Destroys D0-D1/A0-A2
MinimizeWin lea MinimizeY(PC),A1
lea MinimizeX(PC),A2
bra.S WindowSize
MaximizeWin lea MaximizeY(PC),A1
lea MaximizeX(PC),A2
* Call: A1 = Function to adjust size in y-direction
* A2 = Function to adjust size in x-direction
WindowSize move.l ib_ActiveWindow(A6),D0
beq.S 2$
move.l D0,A0
move.l wd_Flags(A0),D0
andi.w #WINDOWSIZING,D0
beq.S 2$
jsr (A1)
move.w D0,D1
jsr (A2)
bne.S 1$
tst.w D1
beq.S 2$
1$ Call SizeWindow
2$ rts
* Call: A0 = Window
MinimizeY move.w wd_MinHeight(A0),D0
sub.w wd_Height(A0),D0
rts
* Call: A0 = Window
MinimizeX move.w wd_MinWidth(A0),D0
sub.w wd_Width(A0),D0
rts
* Call: A0 = Window
MaximizeY move.l wd_WScreen(A0),A1
move.w sc_Height(A1),D0
sub.w wd_TopEdge(A0),D0
cmp.w #$FFFF,wd_MaxHeight(A0)
beq.S 1$
cmp.w wd_MaxHeight(A0),D0
ble.S 1$
move.w wd_MaxHeight(A0),D0
1$ sub.w wd_Height(A0),D0
rts
* Call: A0 = Window
MaximizeX move.l wd_WScreen(A0),A1
move.w sc_Width(A1),D0
sub.w wd_LeftEdge(A0),D0
cmp.w #$FFFF,wd_MaxWidth(A0)
beq.S 1$
cmp.w wd_MaxWidth(A0),D0
ble.S 1$
move.w wd_MaxWidth(A0),D0
1$ sub.w wd_Width(A0),D0
rts
* Refresh the active windows border and gadgets
* Destroys D0-D1/A0-A1
RefreshWin move.l ib_ActiveWindow(A6),D0
beq.S 1$
move.l D0,A0
CallLib RefreshWindowFrame
1$ rts
* »»»»»»»»»»»»»»»»»»» Screen manipulating functions ««««««««««««««««««
* BackScrToFront()
* Bring the bottom-most screen to the top, and activate its top window.
* While there is a screen following the active one, move the the next screen.
* Bring that screen to the front and find its top window. If one was found,
* activate the window.
* Destroys D0-D1/A0-A1
BackScrToFront Call BottomScreen
beq.S 1$
move.l D0,A0
PushS A0
Call ScreenToFront
PopS A0
Call TopWindow
beq.S 1$
move.l D0,A0
Call ActivateWindow
1$ rts
* FrontScreenToBack()
* Move the top screen to the back and activate the top window on the new
* top screen.
* Destroys D0-D1/A0-A1
FrontScrToBack Call TopScreen
beq.S 1$
move.l D0,A0
PushS A0
Call ScreenToBack
PopS A0
Call TopWindow
beq.S 1$
move.l D0,A0
Call ActivateWindow
1$ rts
Planes EQUR D2
Index EQUR D3
WScreen EQUR A2
WBitMap EQUR A3
WViewPort EQUR A4
LORESMAX =6
HIRESMAX =4
* Subtracts a bitplane from the active screen.
* HAM-screens won't be touched.
* EHB-screens won't be EHB-screens after this.
* Destroys D0-D3/A0-A4
SubBitplane Call ASCommon
beq.S 2$
move.w vp_Modes(WViewPort),D0
andi.w #V_HAM,D0
bne.S 2$ ; Don't touch HAM
subq.w #1,Planes
beq.S 2$
move.b Planes,bm_Depth(WBitMap)
move.w Planes,Index
mulu #4,Index
move.l bm_Planes(WBitMap,Index),A0
clr.l bm_Planes(WBitMap,Index)
move.w sc_Width(WScreen),D0
move.w sc_Height(WScreen),D1
move.l GFXbase(PC),A6
CallLib FreeRaster
cmp.b #LORESMAX,Planes
bge.S 1$
andi.w #~V_EHB,vp_Modes(a1) ; Clear EHB flag
1$ move.l INTUIbase(PC),A6
CallLib RemakeDisplay
2$ rts
* Adds a bitplane to the active screen (if enough CHIP-memory).
* HIRES-screens can get a maximum of 4 bitplanes.
* LORES-screens can get a maximum of 6 bitplanes (6 bitplanes means EHB).
* Destroys D0-D3/A0-A4
AddBitplane Call ASCommon
beq.S 3$
move.w Planes,Index
mulu #4,Index
addq.w #1,Planes
moveq #HIRESMAX,D1
move.w vp_Modes(WViewPort),D0
andi.w #V_HIRES,D0 ; HIRES ?
bne.S 1$
moveq #LORESMAX,D1
1$ cmp.w D1,Planes
bgt.S 3$
move.w sc_Width(WScreen),D0
move.w sc_Height(WScreen),D1
move.l GFXbase(PC),A6
CallLib AllocRaster
move.l D0,bm_Planes(WBitMap,Index)
beq.S 3$
move.l D0,A1
move.w bm_Rows(WBitMap),D0
swap D0
move.w bm_BytesPerRow(WBitMap),D0
moveq #2,D1
CallLib BltClear
move.b Planes,bm_Depth(WBitMap)
cmp.w #LORESMAX,Planes
blt.S 2$
ori.w #V_EHB,vp_Modes(WViewPort) ; Depth >= 6 => set EHB flag !
2$ move.l INTUIbase(PC),A6
CallLib RemakeDisplay
3$ rts
ASCommon move.l ib_ActiveScreen(A6),D0
beq.S 1$
move.l D0,WScreen
lea sc_BitMap(WScreen),WBitMap
lea sc_ViewPort(WScreen),WViewPort
moveq #0,Planes
move.b bm_Depth(WBitMap),Planes
1$ rts
* »»»»»»»»»»»»»»»»»»» Misc manipulating functions ««««««««««««««««««««
* Enables/Disables RAWKEY/RAWMOUSE events
* Destroys D0-D1/A0-A1
ToggleInputLock lea StatusBits(PC),A0
bchg #HInputDisabled,(A0)
beq.S BlankScreen
bra.S BreakSBlanking
* Enables/Disables mouse-acceleration
* Destroys D0-D1/A0-A1
ToggleFastMouse lea StatusBits(PC),A0
bchg #HAccelMouse,(A0)
rts
* Enables/Disables sun-mouse
* Destroys D0-D1/A0-A1
ToggleSunMouse lea StatusBits(PC),A0
bchg #HSunMouse,(A0)
rts
* »»»»»»»»»»»»»»» Misc functions called by handler «««««««««««««««««««
* Blanks the screen by installing a temporary copper-list, which
* ensures a black display, and then turning the raster-DMA off.
BlankScreen Push D1-D7/A0-A2/A6
Prepare Exec_Call
CallLib Forbid
lea StatusBits(PC),A0
bset #HScreenBlanked,(A0)
move.l GFXbase(PC),A6
move.l gb_ActiView(A6),A1
move.l v_LOFCprList(A1),A2
movem.w (A2),D2-D7 ; Save CprList (10 bytes)
clr.l crl_Next(A2)
move.l NewCopper(PC),crl_start(A2)
CallLib LoadView ; Install a one-color copperlist
OFF_DISPLAY
movem.w D2-D7,(A2) ; Restore CprList (10 bytes)
Prepare Exec_Call
CallLib Permit
Pop D1-D7/A0-A2/A6
rts
* Sets new screen-blanking timeout and turns the raster-DMA
* back on, if it is off.
BreakSBlanking move.l PWkSTimeout(PC),D0
beq.S 1$
add.l Seconds(Event),D0
1$ lea PWkSWaitTime(PC),A0
move.l D0,(A0)
lea StatusBits(PC),A0
bclr #HScreenBlanked,(A0)
beq.S 2$
PushS A6
move.l GFXbase(PC),A6
move.l gb_ActiView(A6),A1
CallLib LoadView
ON_DISPLAY
PopS A6
2$ rts
* Blanks the mouse by installing an invisible image for sprite 0
* in the copper-list
BlankMouse PushS A6
Prepare Exec_Call
CallLib Forbid
move.l GFXbase(PC),A1
move.l gb_copinit(A1),A1
lea copinit_sprstrtup(A1),A1
cmp.w #$0120,(A1)
bne.S 2$
cmp.w #$0122,4(A1)
bne.S 2$
lea StatusBits(PC),A0
bset #HMouseBlanked,(A0)
bne.S 1$
lea OldSprite(PC),A0
move.w 2(A1),(A0)+
move.w 6(A1),(A0)
1$ lea NewSprite(PC),A0
move.w (A0)+,2(A1)
move.w (A0),6(A1)
2$ Prepare Exec_Call
CallLib Permit
PopS A6
rts
* Sets new mouse-blanking timeout and restores the old
* sprite 0 image, if the mouse is off.
BreakMBlanking PushS A6
move.l PWkMTimeout(PC),D0
beq.S 1$
add.l Seconds(Event),D0
1$ lea PWkMWaitTime(PC),A0
move.l D0,(A0)
lea StatusBits(PC),A0
bclr #HMouseBlanked,(A0)
beq.S 2$
Prepare Exec_Call
CallLib Forbid
move.l GFXbase(PC),A1
move.l gb_copinit(A1),A1
move.w OldSprite+0(PC),copinit_sprstrtup+2(A1)
move.w OldSprite+2(PC),copinit_sprstrtup+6(A1)
Prepare Exec_Call
CallLib Permit
2$ PopS A6
rts
* Activate the window the mouse is over (if any, and if it is not
* already active).
ib_MouseY =ib_FirstScreen+8
ib_MouseX =ib_MouseY+2
ActivateMWindow Push D1-D2/A0-A2/A6
Prepare Exec_Call
CallLib Forbid
move.l INTUIbase(PC),A2
move.l ib_FirstScreen(A2),A1
ScrSLoop move.l A1,D0
beq.S DoneAMW ; Out of screens ?
move.w ib_MouseX(A2),D0
move.w ib_MouseY(A2),D1
move.w sc_ViewPort+vp_Modes(A1),D2
btst #15,D2
bne.S WasHIRES
asr.w #1,D0
WasHIRES btst #2,D2
bne.S WasLACE
asr.w #1,D1
WasLACE sub.w sc_ViewPort+vp_DyOffset(A1),D1
bge.S FoundScr
move.l sc_NextScreen(A1),A1
bra.S ScrSLoop
FoundScr lea sc_LayerInfo(A1),A0 ; Mouse is on this screen
move.l LAYERbase(PC),A6
CallLib WhichLayer
tst.l D0
beq.S DoneAMW ; No layer ?
move.l D0,A0
move.l lr_Window(A0),D0
beq.S DoneAMW ; No window ?
move.l INTUIbase(PC),A6
cmp.l ib_ActiveWindow(A6),D0
beq.S DoneAMW
move.l D0,A0
Call ActivateWindow
DoneAMW Prepare Exec_Call
CallLib Permit
Pop D1-D2/A0-A2/A6
rts
* Call: D0:16 = ie_X/ie_Y
* Return: D0:16 = modified ie_X/ie_Y
* Calculates new mouse position using acceleration and threshold.
CalcNewPos tst.w D0
bge.S 2$
add.w Thresh,D0
bge.S 1$
mulu Accel,D0
1$ sub.w Thresh,D0
rts
2$ sub.w Thresh,D0
ble.S 3$
mulu Accel,D0
3$ add.w Thresh,D0
rts
HandlerSize =*-IHS
* The data below goes into CHIP memory
ChipData
MyCopperList dc.w $0180,$0000 ; Copperlist that ensures
dc.w $FFFF,$FFFE ; a one-color display (black)
MySprite dc.w $FE00,$FF00 ; Invisible sprite
dc.w $0000,$0000
dc.w $0000,$0000
ChipSize =*-ChipData
* »»»»»»»»»»»»»»»»»»»»»» Input-handler end «««««««««««««««««««««««««««
END
* »»»»»»»»»»»»»»»»»»»»»»»»»» The End «««««««««««««««««««««««««««««««««